<?php
/**
 *  💡 免责声明：本软件不得用于商业用途，仅做学习交流
 *  ⚠️ 权利声明：本软件由版权人提供产品技术支持
 *  📅 项目编号：NX2025-0135
 */
namespace App\Service\AdvanceCard;

use App\Models\AdvanceCard;
use App\Models\AdvanceCardSetting;
use App\Models\AdvanceCardTransaction;
use App\Models\GroupOrder;
use App\Models\User;
use App\Service\BaseService;
use App\Service\Notifications\NotificationService;
use App\Service\Setting\BeanSettingService;
use App\Service\User\BeanAccountService;
use App\Service\User\WalletAccountService;

class AdvanceCardService extends BaseService
{
    public function apply_($user_id, $total_count) //申请
    {
        $advanceCard = AdvanceCard::query()
            ->where('user_id', $user_id)
            ->where('status', '<', 3)
            ->first();

        if (filled($advanceCard)) {
            return [
                'flag' => false,
                'msg' => '已存在垫付卡!无法提交申请',
            ];
        }
        $calculateTheCost = $this->calculateTheCost($total_count);
//        if (blank($calculateTheCost)) {
//            return [
//                'flag' => false,
//                'msg' => '超过最大申请垫付次数!无法提交申请',
//            ];
//        }

        $walletAccountService = walletAccountService::make()->consumption($user_id, $calculateTheCost['deposit_amount'], '申请垫付卡存入保证金:' . $calculateTheCost['deposit_amount']);
        if (! $walletAccountService) {
            return [
                'flag' => false,
                'msg' => '钱包金额不足!无法提交申请',
            ];
        }
        $msg = sprintf('申请垫付卡 垫付次数:%s 垫付金:%s 消耗KC通证:%s', $total_count, $calculateTheCost['deposit_amount'], $calculateTheCost['bean']);
        if ($calculateTheCost['bean'] > 0) {
            $beanAccountService = beanAccountService::make()->consumption($user_id, $calculateTheCost['bean'], $msg);
            if (blank($beanAccountService)) {
                return [
                    'flag' => false,
                    'msg' => 'KC通证不足!无法提交申请',
                ];
            }
            beanSettingService::make()->increaseTheAmountOfCombustion($calculateTheCost['bean'], $msg);
        }
        $res = AdvanceCard::query()->create([
            'user_id' => $user_id,
            'total_count' => $total_count,
            'deposit_amount' => $calculateTheCost['deposit_amount'],
            'consume_beans' => $calculateTheCost['bean'],
            'remainder_count' => $total_count,
            'remainder_amount' => $calculateTheCost['deposit_amount'],
            'status' => 2,
        ])->refresh();
        $this->record(
            $res->user_id,
            $res->id,
            $calculateTheCost['deposit_amount'],
            $calculateTheCost['deposit_amount'],
            1,
            1,
            '申请垫付卡 充值垫付款:' . $calculateTheCost['deposit_amount'],
            0,
            $calculateTheCost['bean']
        );
        return [
            'flag' => true,
            'msg' => '申请已提交',
        ];
    }

    public function recharge($advanceCard, $amount) //充值
    {
        if (blank($advanceCard)) {
            return [
                'flag' => false,
                'msg' => '没有可用的垫付卡!',
            ];
        }
        $setting = $this->getSetting();

        $account = WalletAccountService::make()->consumption($advanceCard->user_id, $amount, '垫付卡充值 充值金额:' . $amount);
        if (! $account) {
            return [
                'flag' => false,
                'msg' => '钱包余额不足',
            ];
        }
        $setting = $this->getSetting();
        $bean = bcmul($amount, $setting->recharge_bean_ratio, 2);
        $msg = sprintf('垫付卡充值 充值金额:%s', $amount);
        if ($bean > 0) {
            $msg = sprintf('垫付卡充值 充值金额:%s 消耗KC通证:%s', $amount, $bean);
            $beanAccountService = beanAccountService::make()->consumption($advanceCard->user_id, $bean, $msg);
            if (blank($beanAccountService)) {
                return [
                    'flag' => false,
                    'msg' => 'KC通证不足!无法提交申请',
                ];
            }
            beanSettingService::make()->increaseTheAmountOfCombustion($bean, $msg);
            $advanceCard->consume_beans = bcadd($advanceCard->consume_beans, $bean, 2);
        }

        $advanceCard->deposit_amount = bcadd($advanceCard->deposit_amount, $amount, 2);
        $advanceCard->save();
        $this->record(
            $advanceCard->user_id,
            $advanceCard->id,
            $amount,
            $advanceCard->deposit_amount,
            1,
            1,
            $msg,
            0,
            1
        );
        return [
            'flag' => true,
            'msg' => $msg,
        ];
    }

    public function consumptionAmount(GroupOrder $groupOrder, AdvanceCard $advanceCard) //消耗金额
    {
        $amount = bcmul($groupOrder->amount, $groupOrder->number, 2);
        $advanceCard->deposit_amount = bcsub($advanceCard->deposit_amount, $amount, 2);
        $advanceCard->save();
        $msg = sprintf('拼单成功扣除：%s', $amount);
        $this->record(
            $advanceCard->user_id,
            $advanceCard->id,
            $amount,
            $advanceCard->deposit_amount,
            2,
            2,
            $msg,
            0
        );
        return [
            'flag' => true,
            'msg' => $msg,
        ];
    }

    public function apply($user_id, $amount)
    {
        $advanceCard = AdvanceCard::query()->firstOrCreate([
            'user_id' => $user_id,
        ], [
            'voucher' => $amount,
            'max_voucher' => $amount,
            'deposit_amount' => 0,
            'consume_beans' => 0,
            'status' => 2,
        ]);
        if ($advanceCard->max_voucher != $amount) {
            $advanceCard->max_voucher = $amount;
            $advanceCard->save();
        }
        $this->record(
            $advanceCard->user_id,
            $advanceCard->id,
            $amount,
            $advanceCard->voucher,
            2,
            1,
            '获得代金券' . $amount,
            0,
            2
        );
    }

    public function voucherRecharge($user_id, $amount, $msg)
    {
        $advanceCard = AdvanceCard::query()->where('user_id', $user_id)->first();
        if (blank($advanceCard)) {
            return false;
        }
        if ($amount == 0) {
            return false;
        }

        $advanceCard->voucher += $amount;
        $advanceCard->save();
        $this->record(
            $advanceCard->user_id,
            $advanceCard->id,
            $amount,
            $advanceCard->voucher,
            1,
            1,
            $msg,
            0,
            2
        );
    }

    public function voucherConsumptionAmount($user_id, $amount, $msg)
    {
        $advanceCard = AdvanceCard::query()->where('user_id', $user_id)->first();
        $voucher = $advanceCard->voucher ?? 0;
        if ($voucher < $amount) {
            return false;
        }
        $advanceCard->voucher -= $amount;
        $advanceCard->save();
        $this->record(
            $advanceCard->user_id,
            $advanceCard->id,
            $amount,
            $advanceCard->voucher,
            2,
            2,
            $msg,
            0,
            2
        );
    }

    public function consumptionFrequency(AdvanceCard $advanceCard) //消耗次数
    {
        if ($advanceCard->remainder_count <= 0) {
            return [
                'flag' => false,
                'msg' => '次数已使用完!',
            ];
        }
        --$advanceCard->remainder_count;
        $advanceCard->save();
        return [
            'flag' => true,
            'msg' => sprintf('当前垫付卡剩余垫付次数:%s', $advanceCard->remainder_count),
        ];
    }

    public function refund(AdvanceCard $advanceCard, $is_fundBean = false) //退款
    {
        if ($advanceCard->remainder_amount > 0) {
            $amount = $advanceCard->remainder_amount;
            WalletAccountService::make()->recharge(
                $advanceCard->user_id,
                $advanceCard->remainder_amount,
                sprintf('垫付卡退款%s', $amount),
                true,
                3
            );
            if ($is_fundBean) {
                BeanAccountService::make()->recharge(
                    $advanceCard->user_id,
                    $advanceCard->consume_beans,
                    sprintf('垫付卡退款 退还KC通证:%s', $advanceCard->consume_beans),
                    true,
                    3
                );
                $advanceCard->consume_beans = 0;
            }
            $advanceCard->status = 4;
            $advanceCard->remainder_amount = 0;
            $advanceCard->save();
            $this->record(
                $advanceCard->user_id,
                $advanceCard->id,
                $amount,
                0,
                3,
                2,
                sprintf('垫付卡退款%s', $amount),
                0,
                0
            );
            return true;
        }
        return false;
    }

    //次数计算金额
    public function calculateTheCost($total_count): array
    {
        $setting = $this->getSetting();
//        if ($total_count > $setting->maximum_number) {
//            return [];
//        }
        $amount = $setting->guarantee_fund;
        return [
            'total_count' => $total_count,
            'deposit_amount' => $setting->guarantee_fund,
            'bean' => bcmul($amount, $setting->bean_ratio, 2),
        ];
    }

    public function getSetting()
    {
        return AdvanceCardSetting::query()->first();
    }

    /**
     * @param $user_id
     * @return null|\Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object
     */
    private function getAdvanceCard($user_id)
    {
        return AdvanceCard::query()->where('user_id', $user_id)->where('status', 2)->first();
    }

    private function record(
        $user_id,
        $advance_card_id,
        $amount,
        $balance,
        $transaction_type,
        $change_type,
        $describe,
        $consume_beans,
        $type = 1
    ) //记录
    {
        AdvanceCardTransaction::query()->create([
            'user_id' => $user_id,
            'advance_card_id' => $advance_card_id,
            'amount' => $amount,
            'balance' => $balance,
            'transaction_type' => $transaction_type,
            'change_type' => $change_type,
            'describe' => $describe,
            'consume_beans' => $consume_beans,
            'status' => 2,
            'type' => $type,
        ]);
//        $user = User::query()->find($user_id);
//        if (filled($user)) {
//            NotificationService::make()->SystemNotify($user, $describe);
//        }
    }
}
